package net.hky365.lowcode.magic.interceptor;

import cn.hutool.core.util.BooleanUtil;
import lombok.extern.slf4j.Slf4j;
import net.hky365.shop.framework.common.util.CommonUtils;
import net.hky365.shop.framework.security.core.LoginUser;
import net.hky365.shop.framework.security.core.util.SecurityFrameworkUtils;
import net.hky365.shop.framework.tenant.core.context.TenantContextHolder;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
import org.ssssssss.magicapi.modules.db.inteceptor.NamedTableInterceptor;
import org.ssssssss.magicapi.modules.db.model.SqlMode;
import org.ssssssss.magicapi.modules.db.table.NamedTable;
import org.ssssssss.magicapi.modules.db.table.Where;
import org.ssssssss.script.MagicScriptEngine;
import org.ssssssss.script.annotation.Comment;

import java.time.LocalDateTime;

/**
 * 数据库操作拦截, 注入登录人相关信息
 *
 * @author hl-king
 */
@Slf4j
@Component
public class MagicTableInterceptor implements NamedTableInterceptor, InitializingBean {
    @Comment("无需登录用户信息")
    public static final String NON_SESSION = "__n_s";
    @Comment("无需租户相关信息")
    public static final String NON_SESSION_TENANT = "__n_t";

    @Override
    public void afterPropertiesSet() throws Exception {
        String tpl = "add default import {} => {}";
        log.info(tpl, NON_SESSION, NON_SESSION);
        MagicScriptEngine.addDefaultImport(NON_SESSION, NON_SESSION);

        log.info(tpl, NON_SESSION_TENANT, NON_SESSION_TENANT);
        MagicScriptEngine.addDefaultImport(NON_SESSION_TENANT, NON_SESSION_TENANT);

        log.info(tpl, "NON_SESSION", NON_SESSION);
        MagicScriptEngine.addDefaultImport("NON_SESSION", NON_SESSION);

        log.info(tpl, "NON_SESSION_TENANT", NON_SESSION_TENANT);
        MagicScriptEngine.addDefaultImport("NON_SESSION_TENANT", NON_SESSION_TENANT);
    }

    /*
     * 执行单表操作之前
     */
    @Override
    public void preHandle(SqlMode sqlMode, NamedTable namedTable) {
        boolean noSession = BooleanUtil.toBoolean(CommonUtils.toString(namedTable.getColumns().remove(NON_SESSION)));
        boolean noTenant = BooleanUtil.toBoolean(CommonUtils.toString(namedTable.getColumns().remove(NON_SESSION_TENANT)));

        LoginUser user = SecurityFrameworkUtils.getLoginUser();

        // 注入表中租户相关字段
        if (!TenantContextHolder.isIgnore()) {
            namedTable.where().and(!noTenant, it -> ((Where) it[0]).eq("tenant_id", TenantContextHolder.getRequiredTenantId()));
        }

        // 非insert or update or 没有操作人 or 不需要注入操作对象, 则不注入操作信息
        if ((sqlMode != SqlMode.INSERT && sqlMode != SqlMode.UPDATE) || noSession || user == null) {
            return;
        }

        // 注入操作人
        if (sqlMode == SqlMode.INSERT) {
            namedTable.column("creator", user.getId());
            // namedTable.column("creator_id", user.getId());
            namedTable.column("create_time", LocalDateTime.now());
        }

        namedTable.column("updater", user.getId());
        // namedTable.column("updater_id", user.getId());
        namedTable.column("update_time", LocalDateTime.now());
    }

}